import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;

import java.io.*;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.List;




/**
 * @description:
 * @Author Felix Torn
 * @create: 2024-06-08 20:02
 **/
public class ZipPasswordCracker implements Runnable {

    private final List<String> passwords;
    private final byte[] zipData;
    private final String extractTo;
    private static volatile boolean stop = false;

    public ZipPasswordCracker(byte[] zipData, String extractTo, List<String> passwords ) {
        this.passwords = passwords;
        this.zipData = zipData;
        this.extractTo = extractTo;
    }
    public static boolean unzipFile(byte[] zipData, String extractTo, List<String> passwords) throws IOException {


        for (String password : passwords) {
            if (stop) break;
            if (tryPassword(zipData, password)) {
                return true;
            }
        }

        return false;
    }
public static boolean tryPassword(byte[] zipData, String password) {
    try {
        // 将ZIP数据写入临时文件
        File tempFile = File.createTempFile("temp_zip", ".zip");
        Files.write(tempFile.toPath(), zipData);

        // 创建ZipFile对象
        net.lingala.zip4j.ZipFile zipFile = new net.lingala.zip4j.ZipFile(tempFile);

        // 尝试解压文件
        zipFile.setPassword(password.toCharArray());
        zipFile.extractAll(System.getProperty("java.io.tmpdir"));

        // 删除临时文件
        tempFile.delete();
        System.out.println("破解成功，密码为: " + password);
        long EndTime = System.currentTimeMillis();
        long duration = EndTime - Main.StartTime;
        System.out.println("代码执行时间：" + duration / 1000 + " 秒");
        return true; // 如果没有抛出异常，则表示密码正确
    } catch (IOException e) {
        // 异常处理，可能是密码错误或者其他问题
        return false;
    }
}

    @Override
    public void run() {
        try {
            unzipFile(this.zipData, this.extractTo, this.passwords);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
